#pragma once

#include <boost/optional.hpp>
#include <boostext/smart_ptr.hpp>

#include <engine.core/math.hpp>

#include "exports.hpp"
#include "Enums.hpp"




namespace Engine
{
	namespace Ui
	{
		// The Placement class needs both widget and widgetptr declarations
		class ENGINE_UI_API Widget;




		/**
		 * The Placement class can be used by Layout subclasses to simply the Widget placement.
		 * The class defines a mapping between widgets and the class itself (Placement::Map) that
		 * is handsome when placing widgets through a certain layout.
		 */
		class ENGINE_UI_API Placement
		{
		public:

			typedef boost::optional<Placement>                 Opt;
			typedef std::pair<boost::shared_ptr<Widget>,Opt>   Pair;
			typedef std::map<boost::shared_ptr<Widget>,Opt>    Map;

			enum Type
			{
				Minimum,
				MinimumCentered,
				OptimumCentered,
				Maximum
			};

		public:

			int2       pos;
			intsize2   size;
			intsize2   reserved;

		private:

			Placement(intsize2 size, intsize2 reserved);

		public:

			/**
			* Places the given widget.
			* When using minimum/maximum, the corresponding width/height from the widget
			* is being used. Only when using OptimumCentered placement, the widget will be centered.
			*/
			static Placement centered(const boost::shared_ptr<Widget>& widget, Type verticalPlacement, Type horizontalPlacement, int height, int width);

			/**
			* Calculate how many widgets need to be given a size.
			*/
			static uint32 remainingWidgets(const Map& sm);
		};
		///////////////////////////////////////////////////////////////////////////////////////////
	}
	///////////////////////////////////////////////////////////////////////////////////////////////
}
///////////////////////////////////////////////////////////////////////////////////////////////////
